#!/usr/bin/python
import simplejson, MuConnection, time
from StringIO import StringIO

""" MuNetworkConfiguration contains all the necisary classes and methods for altering the network
	configuration of the Mu Test Suite Appliance
	
	example URLs for the Mu NetConfig API
	-------------------------------------------------------------------------------
	https://MyMu/restlet/netconfig/						----> gets all
	https://MyMu/restlet/netconfig/hosts/				----> gets all hosts
	https://MyMu/restlet/netconfig/routes/				----> gets all routes
	https://MyMu/restlet/netconfig/interfaces/			----> gets all interfaces
	https://MyMu/restlet/netconfig/hosts/myHostName1 	----> gets a host
	https://MyMu/restlet/netconfig/interfaces/a2.101	----> gets an interface
	https://MyMu/restlet/netconfig/routes/192.168.100.0	----> gets a route
	-------------------------------------------------------------------------------

	If request is good you get a jason object back.
	If request is bad and an URL error or jason object containing an error is returned:
	{
		"ERROR_DESCRIPTION": "Get failed, 192.168.110.0 does not exist.",
		"ERROR_NAME": "NetworkConfigError"
	}
	
	Classes contained:
	MuNetworkConfig - instantiated by passing in a MuConnection and is used to mannage the Mu 
		network configuration.
	
	interface - used to represent a Mu Interfaces
	
	host - used to represent a host entry in the Mu host table. This object can contain sshChannels, 
		telnetChannels, or consoleChannels.
	
	route - used to represent a route for a mu interface.
	
	sshChannel - used to represent a ssh channel for a Host. This object can contain a list of 
		commands.
	
	telnetChannel - used to represent a telnet channel for a Host. This object can contain a list 
		of commands
	
	consoleChannel - used to represent a console channel for a Host. This object can contain a list 
		of commands
	
	command - used to represent a setup command for a channel. normaly used to ensure correct 
		login and privledge level is reached
	
"""



#connection = None

class MuNetworkConfig():
	""" MuNetworkConfig: This class is instantiated by passing in a MuConnection and is used to mannage 
		the Mu network configurations.
		----------------------------------------------------------------------------------------------	
		example JSON config data
		[{'interfaces': [{'display_name': 'A1','mac': '00:04:23:c8:eb:04','name': 'a1','up': True,'v4_addrs': ['192.168.100.201','192.168.100.202','192.168.100.203'],'v4_dhcp': False,'v4_dhcp_status': 'DISABLED','v4_mask': '24','v6_global_addrs': ['2003:0:0:0:0:0:0:10','2003:0:0:0:0:0:0:11','2003:0:0:0:0:0:0:12','2003:0:0:0:0:0:0:13'],'v6_global_mask': '64','v6_local_addr': '','vlan': ''},
			{'display_name': 'A2','mac': '00:04:23:c8:ed:78','name': 'a2','up': True,'v4_addrs': ['192.168.100.210','192.168.100.211'],'v4_dhcp': False,'v4_dhcp_status': 'DISABLED','v4_mask': '24','v6_global_addrs': ['2003:0:0:0:0:0:0:20','2003:0:0:0:0:0:0:21'],'v6_global_mask': '64','v6_local_addr': '','vlan': ''},
			{'display_name': 'Mgmt','mac': '00:30:48:8a:21:88','name': 'eth0','up': True,'v4_addrs': ['192.168.1.254'],'v4_dhcp': False,'v4_dhcp_status': 'DISABLED','v4_mask': '24','v6_global_addrs': [],'v6_global_mask': '','v6_local_addr': 'fe80:0:0:0:230:48ff:fe8a:2188','vlan': ''},
			{'display_name': 'Aux','mac': '00:30:48:8a:21:89','name': 'eth1','up': True,'v4_addrs': ['192.168.22.1'],'v4_dhcp': False,'v4_dhcp_status': 'DISABLED','v4_mask': '24','v6_global_addrs': [],'v6_global_mask': '','v6_local_addr': '','vlan': ''},
			{'display_name': 'A2.101','mac': '00:04:23:c8:ed:78','name': 'a2.101','up': True,'v4_addrs': [],'v4_dhcp': False,'v4_dhcp_status': 'DISABLED','v4_mask': '','v6_global_addrs': [],'v6_global_mask': '','v6_local_addr': 'fe80:0:0:0:204:23ff:fec8:ed78','vlan': 101},
			{'display_name': 'A2.102','mac': '00:04:23:c8:ed:78','name': 'a2.102','up': True,'v4_addrs': [],'v4_dhcp': False,'v4_dhcp_status': 'DISABLED','v4_mask': '','v6_global_addrs': [],'v6_global_mask': '','v6_local_addr': 'fe80:0:0:0:204:23ff:fec8:ed78','vlan': 102}]},
		{'routes': [{'default': False,'direct': True,'dst': '192.168.100.0','dst_pfx_len': 24,'gateway': '0.0.0.0','interface': 'a1','interface_display_name': 'A1','metric': 0,'readonly': True},
			{'default': False,'direct': True,'dst': '192.168.22.0','dst_pfx_len': 24,'gateway': '0.0.0.0','interface': 'eth1','interface_display_name': 'Aux','metric': 0,'readonly': True},
			{'default': False,'direct': True,'dst': '192.168.1.0','dst_pfx_len': 24,'gateway': '0.0.0.0','interface': 'eth0','interface_display_name': 'Mgmt','metric': 0,'readonly': True},
			{'default': False,'direct': False,'dst': '192.168.1.0','dst_pfx_len': 24,'gateway': '192.168.100.1','interface': 'a1','interface_display_name': 'A1','metric': 0,'readonly': False},
			{'default': False,'direct': True,'dst': '169.254.0.0','dst_pfx_len': 16,'gateway': '0.0.0.0','interface': 'eth1','interface_display_name': 'Aux','metric': 0,'readonly': True}]},
		{'hosts': [{'mac': '','name': 'HostName2','notes': '','v4_addr': '192.168.1.199','v6_global_addr': '','v6_local_addr': ''},
			{'mac': '','name': 'HostName','notes': '','v4_addr': '192.168.1.253','v6_global_addr': '','v6_local_addr': ''}]}]
		----------------------------------------------------------------------------------------------	

		Arguments: 
		MuConnection - The connection class for maintaining a SSL session to the Mu Test Suite

		Globals:
		VERBOSE - turn on debug printing
		__MuJasonConfig - JSON config from Mu
		muConnection - connection to the Mu Test Server
	
		TODO:
		Need to implement a logging method
	"""

	VERBOSE = False
	__MuJasonConfig = None
   	muConnection = None
   	

	def __init__(self,connection):
		""" set up the TestAPI with the passed in MuConnection """
		self.muConnection = connection

	def downloadNetworkConfigObject(self, url=''):
		""" download a root network config JSON object from the Mu test server
			Example URL: https://$MU_IP/restlet/netconfig/
			
			Arguments:
			url - the url of the desired netconfig object to be retrieved
			
			Returns:
			JSON formated list
		"""
		load = False
		if url=='':
			url = self.muConnection.TOP_LEVEL_URL + "/restlet/netconfig/"
			load = True
		elif url.endswith("/restlet/netconfig/"):
			load = True
		else:
			return {"ERROR":"Invalid url-> "+url}
		responseBuffer = self.muConnection.getRequestBuffer(url)
		jsonConfigObject = simplejson.load(responseBuffer)
		if load:
			self.__MuJasonConfig = jsonConfigObject
		return jsonConfigObject
		
	# Just tries to get some web response and returns the raw data
	def getNetworkConfigObjectData(self, url, isJasonResponse=False):
		""" used to get specific JSON data from the Mu. Uses the GET method
			
			Arguments:
			url - the url of the desired netconfig object to be retrieved
			isJasonResponse - used to indicate that the returned data should be processed as a JSON object
			
			Returns:
			MuConnection.MuResponseObject
		"""
		responseData = self.muConnection.get(url,isJasonResponse)
		return responseData
	
	
	def addNetworkConfigObject(self, url, jsonDataToSend, isJsonResponse = False):
		""" used to add specific JSON data to the Mu. Uses the POST method
			
			Arguments:
			url - the url of the desired netconfig object to be retrieved
			jsonDataToSend - JSON formated objet to send to Mu
			isJasonResponse - used to indicate that the returned data should be processed as a JSON object
			
			Returns:
			MuConnection.MuResponseObject
		"""
		responseData = self.muConnection.post(url,jsonDataToSend,"application/json; charset=utf-8",isJsonResponse)
		return responseData
	
	def modifyNetworkConfigObject(self, url, jsonDataToSend, isJsonResponse = False):
		""" used to modify existing JSON data on the Mu. Uses the PUT method
			
			Arguments:
			url - the url of the desired netconfig object to be retrieved
			jsonDataToSend - JSON formated objet to update on the Mu
			isJasonResponse - used to indicate that the returned data should be processed as a JSON object
			
			Returns:
			MuConnection.MuResponseObject
		"""
		responseData = self.muConnection.put(url,jsonDataToSend,"application/json; charset=utf-8",isJsonResponse)
		return responseData
		
	def deleteNetworkConfigObject(self, url, isJasonResponse=False):
		""" used to delete existing JSON data on the Mu. Uses the DELETE method
			
			Arguments:
			url - the url of the desired netconfig object to be retrieved
			isJasonResponse - used to indicate that the returned data should be processed as a JSON object
			
			Returns:
			MuConnection.MuResponseObject
		"""
		responseData = self.muConnection.delete(url, isJasonResponse)
		return responseData
		
	def addHost(self,hostToAdd):
		""" used to add a network host to the Mu server
			Example URL: https://$MU_IP/restlet/netconfig/hosts/
			
			Arguments:
			hostToAdd - the MuNetworkConfiguration.host object to add to the Mu server network 
				configuration
			
			Returns:
			MuConnection.MuResponseObject
		"""
		jsonString = simplejson.dumps(hostToAdd.getHostData())
		url = self.muConnection.TOP_LEVEL_URL + '/restlet/netconfig/hosts/'
		response = self.addNetworkConfigObject(url,jsonString,True)
		if self.VERBOSE:
			print response
		return response
	
	def deleteHost(self, hostToDelete):
		""" used to delete a network host on the Mu server
			Example URL: https://$MU_IP/restlet/netconfig/hosts/myHostnameToDelete
			
			Arguments:
			hostToDelete - the MuNetworkConfiguration.host object to delete on the Mu server network 
				configuration
			
			Returns:
			MuConnection.MuResponseObject
		"""
		url = self.muConnection.TOP_LEVEL_URL + '/restlet/netconfig/hosts/' + hostToDelete.getName()
		response = self.deleteNetworkConfigObject(url, True)
		if self.VERBOSE:
			print response
		return response
	
	def modifyHost(self, hostToModify):
		""" used to modify a network host on the Mu server
			Example URL: https://$MU_IP/restlet/netconfig/hosts/myHostnameToModify
			
			Arguments:
			hostToModify - the MuNetworkConfiguration.host object used to base modifications on the 
				Mu server network configuration
			
			Returns:
			MuConnection.MuResponseObject
		"""
		jsonString = simplejson.dumps(hostToModify.getHostData())
		url = self.muConnection.TOP_LEVEL_URL + '/restlet/netconfig/hosts/' + hostToModify.getName()
		response = self.modifyNetworkConfigObject(url,jsonString)
		if response.isCompleted()==False:
			result = False
		else:
			result = True
		if self.VERBOSE:
			print response
		return response
			
		
	def isHostPresent(self, hostName=''):
		""" used to check for the presense of a host on the Mu server
			Example URL: https://$MU_IP/restlet/netconfig/hosts/myHostnameToCehck
			
			Arguments:
			hostName - the hostname to search for on the Mu server 
			
			Returns:
			boolean
		"""
		url = self.muConnection.TOP_LEVEL_URL + '/restlet/netconfig/hosts/' + hostName
		response = self.getNetworkConfigObjectData(url,True)
		if response.isCompleted()==False:
			result = False
		elif response.hasError()==True:
			result = False
		else:
			result = True
		if self.VERBOSE:
			print response
		return result
		
	def getHost(self, hostName=''):
		""" used to get a network host on the Mu server
			Example URL: https://$MU_IP/restlet/netconfig/hosts/myHostnameToGet
			
			Arguments:
			hostName - the hostname to get from the Mu server
			
			Returns:
			MuNetworkConfiguration.host object
		"""
		url = self.muConnection.TOP_LEVEL_URL + '/restlet/netconfig/hosts/' + hostName
		response = self.getNetworkConfigObjectData(url,True)
		if response.isCompleted():
			hostData = host(response.getJsonObject())
		else:
			hostData = None
		if self.VERBOSE:
			print response
		return hostData
	
	def getHostList(self):
		""" used to get a JSON list of all hosts on the Mu server
			
			Arguments:
			none
			
			Returns:
			JSON formated object list of all hosts on the Mu serer
		"""
		self.downloadNetworkConfigObject()
		return self.__MuJasonConfig[2]['hosts']
	
	def setHostList(self, jsonFormatedList):
		""" not realy used and will probably go away """
		self.__MuJasonConfig[2]['hosts'] = jsonFormatedList
	
	def getInterfaceList(self):
		""" used to get a JSON list of all interfaces on the Mu server
			
			Arguments:
			none
			
			Returns:
			JSON formated object list of all interfaces on the Mu serer
		"""	
		self.downloadNetworkConfigObject("")
		return self.__MuJasonConfig[0]['interfaces']
		
	def setInterfaces(self, jsonFormatedList):
		""" not realy used and will probably go away """
		self.__MuJasonConfig[0]['interfaces'] = jsonFormatedList
	
	def addInterface(self, interfaceToAdd):
		""" used to add a network interface to the Mu server. You can only add a vlan nterface. 
			When adding a vlan only name and vlan are added first, then a modify with everything 
			else is done.
			
			Arguments:
			interfaceToAdd - the MuNetworkConfiguration.interface object to add to the Mu server 
			
			Returns:
			MuConnection.MuResponseObject
		"""
		tmpVal = interfaceToAdd.getName()
		tmpVal = tmpVal.split(".")
		if len(tmpVal)==2:
			name = tmpVal[0]
			vlan = tmpVal[1]
			dualTag = False
		elif len(tmpVal)==3:
			name = tmpVal[0] + "." + tmpVal[1]
			vlan = tmpVal[2]
			dualTag = True
		else:
			print "ERROR: UNKNOWN VLAN FORMAT FOR INTERFACE"
		response = self.addVlan(name, vlan, dualTag)
		if response.isCompleted()==False or response.hasError():
			return response
		else:
			response = self.modifyInterface(interfaceToAdd)
		return response
		
	def addVlan(self, interfaceName, vlan, dualTag=False):
		""" used to add a vlan interface to the Mu server. When adding a vlan only name and vlan are 
			added first. There is a 5 sec delay added to this command to ensure completion of nterface 
			before command is completed.
			
			Arguments:
			interfaceName - string of the parent interface to add sub vlan interface. a1 --> a1.101, 
				a1.101 --> a1.101.1001
			vlan - the string containing the vlan tag of the new sub inerface.
			
			Returns:
			MuConnection.MuResponseObject
		"""
		tmpJsonData = {'vlan':vlan,'name':interfaceName}
		jsonString = simplejson.dumps(tmpJsonData)
		url = self.muConnection.TOP_LEVEL_URL + '/restlet/netconfig/interfaces/'
		response = self.addNetworkConfigObject(url,jsonString, True)
		if self.VERBOSE:
			print response
		time.sleep(5) # delay used to ensure vlan interface is created before modification is attempted
		return response
	
	def deleteInterface(self, interfaceToDelete):
		""" used to delete a interface on the Mu server. Only vlan interfaces can bedeleted. All 
			routes for the interace are also deleted 
			
			Arguments:
			interfaceToDelete - the MuNetworkConfiguration.interface object to delete on the Mu server 
			
			Returns:
			MuConnection.MuResponseObject
		"""
		url = self.muConnection.TOP_LEVEL_URL + '/restlet/netconfig/interfaces/' + interfaceToDelete.getName()
		response = self.deleteNetworkConfigObject(url, True)
		if response.isCompleted()==False:
			result = False
		else:
			result = True
		if self.VERBOSE:
			print response
		return response
	
	def modifyInterface(self, interfaceToModify):
		""" used to mofify an existing interface on the Mu server.
			
			Arguments:
			interfaceToModify - the MuNetworkConfiguration.interface object to modify on the Mu server 
			
			Returns:
			MuConnection.MuResponseObject
		"""
		jsonString = simplejson.dumps(interfaceToModify.getInterfaceData())
		url = self.muConnection.TOP_LEVEL_URL + '/restlet/netconfig/interfaces/' + interfaceToModify.getName()
		response = self.modifyNetworkConfigObject(url,jsonString, True)
		if response.isCompleted()==False:
			result = False
		else:
			result = True
		if self.VERBOSE:
			print response
		return response
		
	def isInterfacePresent(self, interfaceName):
		""" used to mofify an existing interface on the Mu server.
			
			Arguments:
			interfaceName - the string containing the interface name on the Mu to check for  
			
			Returns:
			boolean
		"""
		url = self.muConnection.TOP_LEVEL_URL + '/restlet/netconfig/interfaces/' + interfaceName
		response = self.getNetworkConfigObjectData(url, True)
		if response.isCompleted()==False:
			result = False
		else:
			result = True
		if self.VERBOSE:
			print response
		return result
		
	def getInterface(self, interfaceName):
		""" used to mofify an existing interface on the Mu server.
			
			Arguments:
			interfaceName - the string containing the interface name on the Mu to get 
			
			Returns:
			MuNetworkConfiguration.interface
		"""
		url = self.muConnection.TOP_LEVEL_URL + '/restlet/netconfig/interfaces/' + interfaceName
		response = self.getNetworkConfigObjectData(url,True)
		if response.isCompleted():
			inerfaceData = interface(response.getJsonObject())
		else:
			inerfaceData = None
		if self.VERBOSE:
			print response
		return inerfaceData
	
	def getRouteList(self):
		""" used to get a JSON list of all routes on the Mu server
			
			Arguments:
			none
			
			Returns:
			JSON formated object list of all routes on the Mu serer
		"""	
		downloadNetworkConfigObject("")
		return self.__MuJasonConfig[1]['routes']
	
	def setRouteList(self, jsonFormatedList):
		""" not realy used and will probably go away """
		self.__MuJasonConfig[1]['routes'] = jsonFormatedList
	
	def addRoute(self, routeToAdd):
		""" used to add a route to the Mu server.
			
			Arguments:
			routeToAdd - the MuNetworkConfiguration.route object to add to the Mu server.
			
			Returns:
			MuConnection.MuResponseObject
		"""
		jsonString = simplejson.dumps(routeToAdd.getRouteData())
		url = self.muConnection.TOP_LEVEL_URL + '/restlet/netconfig/routes/'
		response = self.addNetworkConfigObject(url,jsonString, True)
		if response.isCompleted()==False:
			result = False
		else:
			result = True
		if self.VERBOSE:
			print response
		return response
	
	def modifyRoute(self, routeToModify):
		""" used to modify a route to the Mu server.
			
			Arguments:
			routeToAdd - the MuNetworkConfiguration.route object to modify on the Mu server.
			
			Returns:
			MuConnection.MuResponseObject
		"""
		jsonString = simplejson.dumps(routeToModify.getRouteData())
		url = self.muConnection.TOP_LEVEL_URL + '/restlet/netconfig/routes/' + routeToModify.getDst()
		response = self.modifyNetworkConfigObject(url,jsonString, True)
		if response.isCompleted()==False:
			result = False
		else:
			result = True
		if self.VERBOSE:
			print response
		return response
	
	def deleteRoute(self, routeToDelete):
		""" used to delete a route to the Mu server.
			
			Arguments:
			routeToAdd - the MuNetworkConfiguration.route object to delete on the Mu server.
			
			Returns:
			MuConnection.MuResponseObject
		"""
		url = self.muConnection.TOP_LEVEL_URL + '/restlet/netconfig/routes/' + routeToDelete.getDst()
		response = self.deleteNetworkConfigObject(url, True)
		if response.isCompleted()==False:
			result = False
		else:
			result = True
		if self.VERBOSE:
			print response
		return response
	
	def isRoutePresent(self, routeDst, routeTnterface=''):
		""" used to check if a route is present on the Mu server. CAUTION: if multiple routes 
			exists for the same network (ie the same network route exisits on a1, b1, a2 etc.),
			then it is possible to get a false positive. It may be more efective to get all routs
			and parse them by interface
			
			Arguments:
			routeDst - the the string representing the host or network destination of the route. 
			routeTnterface - TODO: string to verrify source of route is on the correct mu interface
			
			Returns:
			MuConnection.MuResponseObject
			
			TODO: change this method to get all routes and pares for exact match.
		"""
		url = self.muConnection.TOP_LEVEL_URL + '/restlet/netconfig/routes/' + routeDst
		response = self.getNetworkConfigObjectData(url, True)
		if response.isCompleted()==False:
			result = False
		else:
			result = True
		if self.VERBOSE:
			print response
		return result
		
	def getRoute(self, routeDst, routeInterface=''):
		""" used to get a route from the Mu server. CAUTION: if multiple routes 
			exists for the same network (ie the same network route exisits on a1, b1, a2 etc.),
			then it is possible to get a route back that is from the incorrect interface. 
			It may be more efective to get all routs and parse them by interface.
			
			Arguments:
			routeDst - the the string representing the host or network destination of the route. 
			routeTnterface - TODO: string to verrify source of route is on the correct mu interface
			
			Returns:
			MuConnection.MuResponseObject
			
			TODO: change this method to get all routes and pares for exact match.
		"""
		url = self.muConnection.TOP_LEVEL_URL + '/restlet/netconfig/routes/' + routeDst
		response = self.getNetworkConfigObjectData(url,True)
		if response.isCompleted():
			routeData = route(response.getJsonObject())
		else:
			routeData = None
		if self.VERBOSE:
			print response
		return routeData
	
	def getMuJsonConfig(self):
		""" get network configuration from the Mu server """
		downloadNetworkConfigObject("")
		return self.__MuJasonConfig
	

        
class interface():
	""" interface: This class represents all elements associated with a Mu interface

		----------------------------------------------------------------------------------------------	
		example JSON config data
		{'display_name': '', 'mac': '00:00:00:00:00:00', 'name': '', 'up': True, 'v4_addrs': [], 
		'v4_dhcp': False, 'v4_dhcp_status': 'DISABLED', 'v4_mask': '', 'v6_global_addrs': [], 
		'v6_global_mask': '', 'v6_local_addr': '', 'vlan': ''}
		----------------------------------------------------------------------------------------------	

		Arguments: 
		jsonData - The JSON formated data used to populate the object

		Globals:
	"""

	def __init__(self,jsonData=None):
		if jsonData==None:
			return
		self.loadFromJsonData(jsonData)
	
	__jsonData ={'display_name': '', 'mac': '00:00:00:00:00:00', 'name': '', 'up': True, 'v4_addrs': [], 'v4_dhcp': False, 
	'v4_dhcp_status': 'DISABLED', 'v4_mask': '', 'v6_global_addrs': [], 'v6_global_mask': '', 'v6_local_addr': '', 'vlan': ''}
	
	def __str__(self):
		return simplejson.dumps(self.__jsonData)
	
	def loadFromJsonData(self, jsonData):
		self.__jsonData=jsonData
		
	def getInterfaceData(self):
		return self.__jsonData
		
	#------- Gets -------------------
	
	def getData(self, key):
		return self.__jsonData[key] 
	
	def getDisplay_name(self):
		return self.getData("display_name")

	def getMac(self):
		return self.getData("mac")
	
	def getName(self):
		return self.getData("name")
	
	def getUp(self):
		return self.getData("up")
		
	def getV4_addrs(self):
		return self.getData("v4_addrs")
		
	def getV4_dhcp(self):
		return self.getData("v4_dhcp")
		
	def getV4_dhcp_status(self):
		return self.getData("v4_dhcp_status")
		
	def getV4_mask(self):
		return self.getData("v4_mask")
		
	def getV6_global_addrs(self):
		return self.getData("v6_global_addrs")
		
	def getV6_global_mask(self):
		return self.getData("v6_global_mask")
		
	def getV6_local_addr(self):
		return self.getData("v6_local_addr")
		
	def getVlan(self):
		return self.getData("vlan")
		
	#------- Sets -------------------
	
	def setData(self, key, data):
		self.__jsonData[key]=data
		
	#def setDisplay_name(self, data):
	#	self.setData("display_name", data)

	def setMac(self, data):
		self.setData("mac", data)
	
	def setName(self, data):
		self.setData("name", data.lower())
		self.setData("display_name", data.upper())
	
	def setUp(self, data):
		self.setData("up", data)
		
	def setV4_addrs(self, data):
		self.setData("v4_addrs", data)
		
	def setV4_dhcp(self, data):
		self.setData("v4_dhcp", data)
		
	def setV4_dhcp_status(self, data):
		self.setData("v4_dhcp_status", data)
		
	def setV4_mask(self, data):
		self.setData("v4_mask", data)
		
	def setV6_global_addrs(self, data):
		self.setData("v6_global_addrs", data)
		
	def setV6_global_mask(self, data):
		self.setData("v6_global_mask", data)
		
	def setV6_local_addr(self, data):
		self.setData("v6_local_addr", data)
		
	def setVlan(self, data):
		self.setData("vlan", data)
	
class host():
	""" host: This class represents all elements associated with a Mu host object

		----------------------------------------------------------------------------------------------	
		example JSON config data
		{'mac': '', 'name': 'VoIP-Server', 'notes': '', 'v4_addr': '192.168.100.51', 
		'v6_global_addr': '', 'v6_local_addr': '', 'ssh_channel': {'commands': [], 'password': 'admin', 
		'prompt': '[#$>]', 'tcp_port': 22, 'username': 'admin'}}
		----------------------------------------------------------------------------------------------	

		Arguments: 
		jsonData - The JSON formated data used to populate the object

		Globals:
	"""

	def __init__(self,jsonData=None):
		if jsonData==None:
			return
		self.loadFromJsonData(jsonData)

	__jsonData = {'mac': '', 'name': 'VoIP-Server', 'notes': '',
	'v4_addr': '192.168.100.51', 'v6_global_addr': '', 'v6_local_addr': ''}
	
	def __str__(self):
		return simplejson.dumps(self.__jsonData)
		
	def loadFromJsonData(self, jsonData):
		self.__jsonData=jsonData
		
	def getHostData(self):
		return self.__jsonData
		
	#------- Gets --------------------
	def getData(self, key):
		try:
			return self.__jsonData[key]
		except KeyError:
			return ''
	
	def getMac(self):
		return self.getData('mac')
		
	def getName(self):
		return self.getData('name')
		
	def getNotes(self):
		return self.getData('notes')
		
	def getTelnet_channel(self):
		return self.getData('telnet_channel')
	
	def getSsh_channel(self):
		return self.getData('ssh_channel')
		
	def getV4_addr(self):
		return self.getData('v4_addr')
		
	def getV6_global_addr(self):
		return self.getData('v6_global_addr')
		
	def getV6_local_addr(self):
		return self.getData('v6_local_addr')
		
	def getConsole_channel(self):
		return self.getData('console_channel')
	
	#------- Sets -------------------
	def setData(self, key, data):
		self.__jsonData[key] = data
	
	def setMac(self, data):
		self.setData('mac', data)
		
	def setName(self, data):
		self.setData('name', data)
		
	def setNotes(self, data):
		self.setData('notes', data)
		
	def setTelnet_channel(self, data):
		self.setData('telnet_channel', data)
		try:
			del self.setData['ssh_channel']
		except KeyError:
			return
		try:
			del self.setData['console_channel']
		except KeyError:
			return
	
	def setSsh_channel(self, data):
		self.setData('ssh_channel', data)
		try:
			del self.setData['telnet_channel']
		except KeyError:
			return
		try:
			del self.setData['console_channel']
		except KeyError:
			return
		
	def setV4_addr(self, data):
		self.setData('v4_addr', data)
		
	def setV6_global_addr(self, data):
		self.setData('v6_global_addr', data)
		
	def setV6_local_addr(self, data):
		self.setData('v6_local_addr', data)
		
	def setConsole_channel(self, data):
		self.setData('console_channel', data)
		try:
			del self.setData['ssh_channel']
		except KeyError:
			return
		try:
			del self.setData['telnet_channel']
		except KeyError:
			return
		

class sshChannel():
	""" sshChannel: This class represents all elements associated with a Mu ssh object and is added to the host object

		----------------------------------------------------------------------------------------------	
		example JSON config data
		'ssh_channel': {'commands': [], 'password': 'admin', 'prompt': '[#$>]', 'tcp_port': 22, 
		'username': 'admin'}
		----------------------------------------------------------------------------------------------	

		Arguments: 
		jsonData - The JSON formated data used to populate the object

		Globals:
	"""
	__channel = {'commands': [], 'password': '', 'prompt': '[#$>]', 'tcp_port': 22, 'username': ''}
	
	def __init__(self,jsonData=None):
		if jsonData==None:
			return
		self.loadFromJsonData(jsonData)
	
	def loadFromJsonData(self, jsonData):
		self.__channel=jsonData
	
	#------- Gets --------------------
	def getData(self, key):
		return self.__channel[key]
		
	def getCommands(self):
		return self.getData('commands')
		
	def getPassword(self):
		return self.getData('password')
	
	def getPrompt(self):
		return self.getData('prompt')
		
	def getTcp_port(self):
		return self.getData('tcp_port')
		
	def getUsername(self):
		return self.getData('username')
		
	#------- Sets -------------------
	def setData(self, key, data):
		self.__channel[key] = data
		
	def setCommands(self, data):
		self.setData('commands', data)
		
	def setPassword(self, data):
		self.setData('password', data)
		
	def setPrompt(self, data):
		self.setData('prompt', data)
		
	def setTcp_port(self, data):
		self.setData('tcp_port', data)
		
	def setUsername(self, data):
		self.setData('username', data)
		

class telnetChannel():
	""" telnetChannel: This class represents all elements associated with a Mu telnet object and is added to the host object

		----------------------------------------------------------------------------------------------	
		example JSON config data
		'telnet_channel': {'commands': [],'prompt': '>', 'tcp_port': 23}
		----------------------------------------------------------------------------------------------	

		Arguments: 
		jsonData - The JSON formated data used to populate the object

		Globals:
	"""
	#'telnet_channel': {'commands': [],'prompt': '>', 'tcp_port': 23}
	__channel ={'commands': [],'prompt': '[$#>]', 'tcp_port': 23}
	
	
	def __init__(self,jsonData=None):
		if jsonData==None:
			return
		self.loadFromJsonData(jsonData)
	
	def loadFromJsonData(self, jsonData):
		self.__channel=jsonData
	
	#------- Gets --------------------
	def getData(self, key):
		return self.__channel[key]
		
	def getCommands(self):
		return self.getData('commands')
		
	def getPrompt(self):
		return self.getData('prompt')
		
	def getTcp_port(self):
		return self.getData('tcp_port')
		
	#------- Sets -------------------
	def setData(self, key, data):
		self.__channel[key] = data
		
	def setCommands(self, data):
		self.setData('commands', data)
		
	def setPrompt(self, data):
		self.setData('prompt', data)
		
	def setTcp_port(self, data):
		self.setData('tcp_port', data)
		
	
class consoleChannel():
	""" consoleChannel: This class represents all elements associated with a Mu console object and is added to the host object

		----------------------------------------------------------------------------------------------	
		example JSON config data
		'console_channel': {'baud_rate': 'BR115200', 'commands': [],'flow_control': 'None','prompt': '[$#>]','serial_port': 'consoleb'}
		----------------------------------------------------------------------------------------------	
	
		Arguments: 
		jsonData - The JSON formated data used to populate the object

		Globals:
	"""
	#'console_channel': {'baud_rate': 'BR115200', 'commands': [],'flow_control': 'None','prompt': '[$#>]','serial_port': 'consoleb'}
	__jsonData ={'baud_rate': 'BR115200', 'commands': [],'flow_control': 'None','prompt': '[$#>]','serial_port': 'consoleb'}

	def __init__(self,jsonData=None):
		if jsonData==None:
			return
		self.loadFromJsonData(jsonData)
	
	def loadFromJsonData(self, jsonData):
		self.__jsonData=jsonData


	def __str__(self):
		return simplejson.dumps(self.__jsonData)

	#------- Gets --------------------
	def getData(self, key):
		return self.__channel[key]
		
	def getCommands(self):
		return self.getData('commands')
		
	def getPrompt(self):
		return self.getData('prompt')
		
	def getSerial_port(self):
		return self.getData('serial_port')
		
	def getBaud_rate(self):
		return self.getData('baud_rate')
		
	def getFlow_control(self):
		return self.getData('flow_control')
		
	#------- Sets -------------------
	def setData(self, key, data):
		self.__channel[key] = data
		
	def setCommands(self, data):
		self.setData('commands', data)
		
	def setPrompt(self, data):
		self.setData('prompt', data)
		
	def setSerial_port(self, data):
		self.setData('serial_port', data)
		
	def setBaud_rate(self, data):
		self.setData('baud_rate', data)
		
	def setFlow_control(self, data):
		self.setData('flow_control', data)


class command():
	""" command: This class represents all elements associated with a Mu channel command object and is added to the telnet, ssh, or console objects

		----------------------------------------------------------------------------------------------	
		example JSON config data
		LIST OF COMMANDS
		{'expect_command': {'regex': 'ogin:', 'timeout': '4s'}}, {'send_command': 
		{'command': 'jbates'}}, {'expect_command': {'regex': 'word:', 'timeout': '4s'}}, 
		{'send_password_command': {'command': 'passW0rd'}}
	
		EXPECT COMMAND
		'expect_command': {'regex': 'ogin:', 'timeout': '4s'}
		SEND COMMAND
		'send_command': {'command': 'admin'}
		SLEEP COMMAND
		'sleep_command': {'delay': '2s'}
		SEND PASSWORD COMMAND
		'send_password_command': {'command': 'admin'}
		----------------------------------------------------------------------------------------------	

		Arguments: 
		jsonData - The JSON formated data used to populate the object

		Globals:
	"""
	__command ={}
	
	def __init__(self,jsonData=None):
		if jsonData==None:
			return
		self.loadFromJsonData(jsonData)
	
	def loadFromJsonData(self, jsonData):
		self.__command=jsonData
	
	def __str__(self):
		return simplejson.dumps(self.__command)

	
	#------- Gets --------------------
	def getData(self, key):
		return self.__jsonData[key]
		
	def getExpect_command(self):
		return self.getData('expect_command')
		
	def getSleep_command(self):
		return self.getData('sleep_command')
		
	def getSend_command(self):
		return self.getData('send_command')
		
	def getSend_password_command(self):
		return self.getData('send_password_command')
		
	#------- Sets -------------------
		
	def setExpect_command(self, regex, timeout='4s'):
		command = ''
		command['expect_command'] = {'regex':regex,'timeout':timeout}
		
	def setSleep_command(self, delay='2s'):
		command = ''
		command['sleep_command'] = {'delay':delay}
		
	def setSend_command(self, command):
		command = ''
		command['send_command'] = {'command':command}
		
	def setSend_password_command(self, password):
		command = ''
		command['send_password_command'] = {'command':password}
		
		
	

class route():
	""" route: This class represents all elements associated with a Mu route object

		----------------------------------------------------------------------------------------------	
		example JSON config data
		'default': False, 'direct': True, 'dst': '169.254.0.0', 'dst_pfx_len': 16, 'gateway': '0.0.0.0', 
		'interface': 'eth1', 'interface_display_name': 'Aux', 'metric': 0, 'readonly': True
		----------------------------------------------------------------------------------------------	

		Arguments: 
		jsonData - The JSON formated data used to populate the object

		Globals:
	"""

	def __init__(self,jsonData=None):
		if jsonData==None:
			return
		self.loadFromJsonData(jsonData)
	
	def loadFromJsonData(self, jsonData):
		self.__jsonData=jsonData	

	def __str__(self):
		return simplejson.dumps(self.__jsonData)

	__jsonData =  {'default': False, 'direct': False, 'dst': '0.0.0.0', 'dst_pfx_len': 24, 
	'gateway': '0.0.0.0', 'interface': '', 'interface_display_name': '', 'metric': 0, 'readonly': False}

	def loadFromJsonData(self, jsonData):
		self.__jsonData=jsonData
		
	def getRouteData(self):
		return self.__jsonData
		
	#-----------Gets--------------------	
	def getDst(self):
		return self.getData('dst')
		
	def getDst_pfx_len(self):
		return self.getData('dst_pfx_len')
		
	def getGateway(self):
		return self.getData('gateway')
		
	def getInterface(self):
		return self.getData('interface')
		
	def getInterface_display_name(self):
		return self.getData('interface_display_name')
		
	def getMetric(self):
		return self.getData('metric')
		
	def getReadonly(self):
		return self.getData('readonly')
		
	def getDefault(self):
		return self.getData('default')
		
	def getDirect(self):
		return self.getData('direct')
		
	def getData(self, key):
		return self.__jsonData[key]
		
	#----------Sets--------------------
	def setDst(self, data):
		self.setData('dst', data)
		
	def setDst_pfx_len(self, data):
		self.setData('dst_pfx_len', data)
		
	def setGateway(self, data):
		self.setData('gateway', data)
		
	def setInterface(self, data):
		#should be all lowercase: a1, a1.1001
		self.setData('interface', data.lower())
		self.setData('interface_display_name', data.upper())
		
	def setInterface_display_name(self, data):
		#shuld be interface in all uppercase: A1, A1.1001
		self.setData('interface_display_name', data)
		
	def setMetric(self, data):
		#metric currently always 0
		data = 0
		self.setData('metric', data)
		
	#def setReadonly(self, data):
	#	self.setData('readonly', data)
		
	#def setDefault(self, data):
	#	self.setData('default', data)
		
	#def setDirect(self, data):
	#	self.setData('direct', data)
	
	def setData(self, key, data):
		self.__jsonData[key] = data


